﻿using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using project1113.Wrold;
using project1113.SomeTools;
using System;
using System.Windows;
using project1113.iniParser;
using project1113.observer;

namespace project1113.Communication
{
    public class Communication
    {
        static string targetIp { get; set; }
        static int targetPort { get; set; }
        static int localPort { get; set; }
        private static UdpClient udpClient;
        private static IPEndPoint remoteEndPoint;
        private static string receivedData;

        private static async Task ListenForUdpDataAsync()
        {
            while (true)
            {
                UdpReceiveResult result = await udpClient.ReceiveAsync();
                receivedData = Encoding.UTF8.GetString(result.Buffer);
                WorldModel.CurrentWorld.Robot.UpdateMessage(receivedData);
                JsonDocument jsonDocument = JsonDocument.Parse(receivedData);
                if (ContainsKey(jsonDocument.RootElement, "result"))
                {
                    //有"result"代表是完成回包
                    WorldModel.CurrentWorld.Robot.freeRobot();
                }
            }
        }
        private static async Task StartReceivingAsync()
        {
            StaticLogWrite.Logger.Log(LogLevel.Info, "！通信开启！"+$"本机端口:{localPort}");
            // 启动监听UDP返回数据的任务
            Task receiveTask = ListenForUdpDataAsync();

        }
        public static void CommunicateInit()
        {
            string iniFilePath = @"conf\RobotConf.ini";
            var iniParser = new IniParser(iniFilePath, new Observe_err());

            try
            {
                targetIp = iniParser.GetSetting("TargetIP") ?? throw new Exception("缺少参数: TargetIP");
                targetPort = int.Parse(iniParser.GetSetting("TargetPort") ?? throw new Exception("缺少参数: TargetPort"));
                localPort = int.Parse(iniParser.GetSetting("LocalPort")?? throw new Exception("缺少参数: LocalPort"));
            }
            catch (Exception e)
            {
                //应该做一下观察器，我就算了,懒得麻烦--zlj
                MessageBox.Show(e.Message);
                StaticLogWrite.Logger.Log(LogLevel.Error, e.Message);
            }
            try
            {
                udpClient = new UdpClient(localPort);
                remoteEndPoint = new IPEndPoint(IPAddress.Parse(targetIp), targetPort);
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
                StaticLogWrite.Logger.Log(LogLevel.Error, e.Message);
            }
            
            StartReceivingAsync();
        }
        public static void sendDate(string date)
        {
            byte[] _date = Encoding.UTF8.GetBytes(date);
            udpClient.Send(_date, _date.Length, remoteEndPoint);
            StaticLogWrite.Logger.Log(LogLevel.Info, $"{targetIp}:" + $"{targetPort}:"+date);
        }
        static bool ContainsKey(JsonElement jsonElement, string targetKey)
        {
            // 如果当前元素是对象类型
            if (jsonElement.ValueKind == JsonValueKind.Object)
            {
                // 遍历对象的属性
                foreach (var property in jsonElement.EnumerateObject())
                {
                    // 如果找到目标键，返回true
                    if (property.NameEquals(targetKey))
                    {
                        return true;
                    }
                    // 递归检查属性值
                    if (ContainsKey(property.Value, targetKey))
                    {
                        return true;
                    }
                }
            }
            // 如果当前元素是数组类型
            else if (jsonElement.ValueKind == JsonValueKind.Array)
            {
                // 遍历数组的元素
                foreach (var item in jsonElement.EnumerateArray())
                {
                    // 递归检查数组元素
                    if (ContainsKey(item, targetKey))
                    {
                        return true;
                    }
                }
            }
            // 如果当前元素不是对象或数组，或者未找到目标键，返回false
            return false;
        }
    }
}
